package com.seestech.sell.web;

import com.seestech.sell.common.utils.Constants;
import com.seestech.sell.common.utils.FileUtils;
import com.seestech.sell.common.utils.StringUtils;
import com.seestech.sell.common.config.ApplicationConfig;
import com.seestech.sell.domain.model.Company;
import com.seestech.sell.domain.model.User;
import com.seestech.sell.service.ICompanyService;
import com.seestech.sell.service.IUserService;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.propertyeditors.CustomDateEditor;
import org.springframework.web.bind.WebDataBinder;
import org.springframework.web.bind.annotation.InitBinder;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.multipart.MultipartFile;
import org.springframework.web.multipart.MultipartHttpServletRequest;

import java.io.File;
import java.text.SimpleDateFormat;
import java.util.*;
import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;


/**
 * Created by idiot on 2017/6/15.
 */
public class SuperController {
    private static Logger logger = LoggerFactory.getLogger(SuperController.class);
    /**
     * @Description 作为基础的控制器，方便调用request，session，response
     *              用ThreadLocal 是因为防止  局部共享变量  导致数据污染
     */
    protected ThreadLocal<HttpServletRequest> request_local = new ThreadLocal<>();
    protected ThreadLocal<HttpServletResponse> response_local = new ThreadLocal<>();
    protected ThreadLocal<HttpSession> session_local = new ThreadLocal<>();

    @Resource
    private IUserService userService;
    @Resource
    private ICompanyService companyService;

    @ModelAttribute
    public void setReqAndRes(HttpServletRequest request, HttpServletResponse response) {
        this.request_local.set(request);
        this.response_local.set(response);
        this.session_local.set(request.getSession());
        User user = getUser();
        if(user != null){
            logger.info("=================>>>>>>>操作用户>>>>>>>>【" + user.getUserName() + "】");
        }
    }

    @InitBinder
    public void initBinder(WebDataBinder binder) {
        SimpleDateFormat dateFormat = new SimpleDateFormat("yyyy-MM-dd hh:mm:ss");
        binder.registerCustomEditor(Date.class, new CustomDateEditor(dateFormat, true));
    }

    //session中获取用户
    protected User getUser(){
        Object info = session_local.get().getAttribute(Constants.Regular.onlineUser);
        if(info != null){
            return (User) info;
        }
        return null;
    }

    /**
     * @description  存储上传的文件 返回是否完成
     * @param file			待上传的文件
     * @param tempFileDir	临时存储的分片文件
     * @param myFileName	文件名
     * @param chunk			当前的“片”
     * @param chunks		总数的“片”
     * @return	是否上传全部的“片”文件
     */
    protected boolean isUploadFileDone(MultipartFile file, File tempFileDir, String myFileName, int chunk, int chunks){
        if (!tempFileDir.exists()) {
            tempFileDir.mkdirs();
        }
        // 分片处理时，前台会多次调用上传接口，每次都会上传文件的一部分到后台(默认每片为5M)
        File tempPartFile = new File(tempFileDir, myFileName + "_" + chunk + ".part");
        //如果文件存在就不用继续上传了
        if(!tempPartFile.exists())
            FileUtils.copyInputStreamToFile(file, tempPartFile);
        else
            logger.info("======>>>>当前分片文件已经存在，不需要重新上传=====>>>>>"+ myFileName + "_" + chunk + ".part");

        // 是否全部上传完成 所有分片都存在才说明整个文件上传完成
        boolean uploadDone = true;
        for (int i = 0; i < chunks; i++) {
            File partFile = new File(tempFileDir, myFileName + "_" + i + ".part");
            if (!partFile.exists()) {
                uploadDone = false;
            }
        }
        return uploadDone;
    }

    /**
     * @description  上传单个图片
     * @param applicationConfig
     * @param filePath
     * @param key    文件的key
     * @return
     */
    protected String uploadImage(ApplicationConfig applicationConfig, String filePath, String key){
        MultipartHttpServletRequest multiRequest = (MultipartHttpServletRequest)request_local.get();
        MultipartFile multipartFile = multiRequest.getFile(key);
        if(multipartFile != null) {
            String path = FileUtils.addPathSeparate(applicationConfig.getBaseDirectory(), filePath);
            //文件名
            String fileName = multipartFile.getOriginalFilename();
            //获取文件拓展名
            String extName = FileUtils.getExtName(fileName);
            //保证 文件夹存在
            File fileDir = FileUtils.buildFileByPath(path);
            File file = new File(fileDir, fileName);
            //拷贝文件流  到上面的文件
            FileUtils.copyInputStreamToFile(multipartFile, file);
            //重命名文件
            String newFileName = System.currentTimeMillis()+StringUtils.randomValue(10000)+"."+extName;
            File finalFile = new File(fileDir, newFileName);
            if(file.renameTo(finalFile)){
                logger.info("================>>>重命名文件成功........."+finalFile.getName());
            }
            String result = FileUtils.getTrulyPath(FileUtils.removeBaseDir(applicationConfig.getUploadUrl(), finalFile.getPath()));
            logger.info("上传图片结果========>>>>>" + result);
            return result;
        }
        return null;
    }

    //获取用户相关的企业信息编号
    public List<Long> getCompanyIdsByUser(User user){
        //根据用户编号获取企业信息  该用户创建的企业  获取 管理的企业
        List<Long> ids = companyService.getCompanyByUserId(user.getUserId());
        //如果用户加入了企业   获取对应的企业信息
        if(user.getCompanyId() != null) {
            Company company = companyService.getCompanyById(user.getCompanyId());
            if(company != null && !ids.contains(company.getId())){
                ids.add(company.getId());
            }
        }
        return ids;
    }

    //获取企业相关的用户信息编号
    public Set<Long> getUserIds(User user){
        Set<Long> userIds = new HashSet<>();
        //根据用户编号获取企业信息  该用户创建的企业  获取 管理的企业
        List<Long> ids = getCompanyIdsByUser(user);
        //根据上面的企业信息获取  对应的用户信息
        if(ids.size() > 0)
            userIds = userService.getUserIdsByCompanyIds(ids);
        return userIds;
    }

}